package com.iot.geteway.config;

import com.iot.geteway.filters.AuthenGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
 * @Author 咕唧
 * @Date 2022/7/19 19:31
 * @Version 1.0
 */
@Configuration
public class GatewayConfig {
    /**
     * 路由规则
     *
     * @param builder
     * @param keyResolver      如和区分限流用户
     * @param redisRateLimiter 限流的策略
     * @return
     */
    @Bean
    public RouteLocator route(RouteLocatorBuilder builder, KeyResolver keyResolver, RedisRateLimiter redisRateLimiter, AuthenGatewayFilterFactory authenGatewayFilterFactory) {

        return builder.routes()
                //设置令牌的路由规则
                .route("tokenroute", predicateSpec -> {
                    return predicateSpec.path("/api/v1/user/login")
                            .filters(gatewayFilterSpec -> {
                                //跳过前缀
                                return gatewayFilterSpec.stripPrefix(2)
                                        //设置限流规则
                                        .requestRateLimiter(config -> {
                                            config.setKeyResolver(keyResolver)
                                                    .setRateLimiter(redisRateLimiter);
                                        });
                            }).uri("lb://iot-auth");
                })
                .route("userroute", predicateSpec -> {
                    return predicateSpec.path("/api/v1/user/**")
                            .filters(gatewayFilterSpec -> {
                                //跳过前缀
                                return gatewayFilterSpec.stripPrefix(2)
                                        //添加过滤器
                                        .filter(authenGatewayFilterFactory.apply(new AuthenGatewayFilterFactory.Config()))
                                        .requestRateLimiter(config -> {
                                            //设置限制规则
                                            config.setKeyResolver(keyResolver).setRateLimiter(redisRateLimiter);
                                        });
                            }).uri("lb://iot-auth");
                })
                .route("tenantRoute", predicateSpec -> {
                    return predicateSpec.path("/api/v1/tenant/**")
                            .filters(gatewayFilterSpec -> {
                                return gatewayFilterSpec.stripPrefix(2)
                                        .filter(authenGatewayFilterFactory.apply(new AuthenGatewayFilterFactory.Config()))
                                        .requestRateLimiter(config -> {
                                            config.setKeyResolver(keyResolver).setRateLimiter(redisRateLimiter);
                                        });
                            }).uri("lb://iot-tenant");
                })
                .build();
    }

    /**
     * 根据用户请求的地址区分
     *
     * @return
     */
    @Bean
    public KeyResolver keyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
    }

    /**
     * 限流的策略 设置限流的规则，表示 每秒钟，1个请求 ，1个令牌数
     *
     * @return
     */
    @Bean
    public RedisRateLimiter redisRateLimiter() {

        return new RedisRateLimiter(1, 1, 1);
    }
}
